package com.reactim.message.protection;

import java.time.Duration;
import java.time.Instant;
import java.util.concurrent.atomic.AtomicInteger;

/**
 * 简单的令牌桶限流器
 */
public class RateLimiter {
    
    private final int maxTokens;
    private final Duration refillInterval;
    private final AtomicInteger tokens;
    private volatile Instant lastRefillTime;
    
    public RateLimiter(int maxTokens, Duration refillInterval) {
        this.maxTokens = maxTokens;
        this.refillInterval = refillInterval;
        this.tokens = new AtomicInteger(maxTokens);
        this.lastRefillTime = Instant.now();
    }
    
    /**
     * 尝试获取一个令牌
     * @return 是否成功获取令牌
     */
    public synchronized boolean tryAcquire() {
        refillTokens();
        
        if (tokens.get() > 0) {
            tokens.decrementAndGet();
            return true;
        }
        
        return false;
    }
    
    /**
     * 补充令牌
     */
    private void refillTokens() {
        Instant now = Instant.now();
        Duration timeSinceLastRefill = Duration.between(lastRefillTime, now);
        
        if (timeSinceLastRefill.compareTo(refillInterval) >= 0) {
            // 重置令牌桶
            tokens.set(maxTokens);
            lastRefillTime = now;
        }
    }
    
    /**
     * 检查是否过度使用（用于异常检测）
     * @return 是否过度使用
     */
    public boolean isExcessive() {
        return tokens.get() <= maxTokens * 0.1; // 当令牌数量低于10%时认为过度使用
    }
    
    /**
     * 检查限流器是否过期
     * @param now 当前时间
     * @return 是否过期
     */
    public boolean isExpired(Instant now) {
        return Duration.between(lastRefillTime, now).toHours() > 1; // 1小时未使用则过期
    }
    
    /**
     * 获取当前可用令牌数
     * @return 可用令牌数
     */
    public int getAvailableTokens() {
        refillTokens();
        return tokens.get();
    }
}